package com.yjz.zpay.hook;


import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.yjz.zpay.db.DBManager;
import com.yjz.zpay.utils.JSONParser;
import com.yjz.zpay.utils.L;
import com.yjz.zpay.utils.PayHelperUtils;
import com.yjz.zpay.utils.StringUtils;

import org.json.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;


/**
 * alipay hook
 *
 * @author yjz
 *         created at 2019/1/18 下午9:42
 */
public class AlipayHook {

    public static String BILLRECEIVED_ACTION = "com.tools.payhelper.billreceived";
    public static ClassLoader mClassLoader;
    static DBManager dbManager;

    public void hook(final ClassLoader classLoader, final Context context) {
        securityCheckHook(classLoader);

        mClassLoader = classLoader;
        dbManager = new DBManager(context);
        try {
            Class<?> insertTradeMessageInfo = XposedHelpers.findClass("com.alipay.android.phone.messageboxstatic.biz.dao.TradeDao", classLoader);
            XposedBridge.hookAllMethods(insertTradeMessageInfo, "insertMessageInfo", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    try {
                        L.log("######支付宝个人账号订单start########=");

                        //获取content字段
                        String content2 = (String) XposedHelpers.getObjectField(param.args[0], "content");
                        L.log("==================" + content2);
                        //获取全部字段
                        Object object = param.args[0];
                        String MessageInfo = (String) XposedHelpers.callMethod(object, "toString");
                        L.log("个人账号订单---->" + MessageInfo);
                        String content = StringUtils.getTextCenter(MessageInfo, "content='", "'");
                        if (content.contains("二维码收款") || content.contains("收到一笔转账")) {
                            JSONObject jsonObject = new JSONObject(content);
                            String money = jsonObject.getString("content").replace("￥", "");
                            String mark = jsonObject.getString("assistMsg2");
                            String tradeNo = StringUtils.getTextCenter(MessageInfo, "tradeNO=", "&");


                            L.log("收到个人账号订单支付宝支付订单：" + tradeNo + "##" + money + "##" + mark);

                            getBillList(context, "D_TRANSFER","1");

                        } else if (content.contains("充值")) {

                            L.log("充值到余额方式----------");
                            getBillList(context, "D_TRANSFER","5");

                        }
                        L.log("######支付宝个人账号订单end########=");
                    } catch (Exception e) {
                        L.log(e.getMessage());
                    }
                    super.beforeHookedMethod(param);
                }
            });

            Class<?> insertServiceMessageInfo = XposedHelpers.findClass("com.alipay.android.phone.messageboxstatic.biz.dao.ServiceDao", classLoader);
            XposedBridge.hookAllMethods(insertServiceMessageInfo, "insertMessageInfo", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    try {
                        L.log("######支付宝商家服务订单start########=");
                        Object object = param.args[0];
                        String MessageInfo = (String) XposedHelpers.callMethod(object, "toString");
                        L.log("商家服务订单-->" + MessageInfo);
                        String content = StringUtils.getTextCenter(MessageInfo, "extraInfo='", "'").replace("\\", "");
                        L.log("#####----->内容:" + content);
//
                        String moneyQr = StringUtils.getTextCenter(MessageInfo, "mainAmount\":\"", "\"");
                        L.log("####---->moneyQr:" + moneyQr);

                        //获取订单列表
                        if (!"error".equals(moneyQr)) {
                            getBillList(context, "TRADE","1");
                        } else {
                            getBillList(context, "D_TRANSFER","5");
                        }

                        L.log("######支付宝商家服务订单end########=");
                    } catch (Exception e) {
                        PayHelperUtils.sendmsg(context, e.getMessage());
                    }
                    super.beforeHookedMethod(param);
                }
            });

            // hook获取loginid
            XposedHelpers.findAndHookMethod("com.alipay.mobile.quinox.LauncherActivity", classLoader, "onResume",
                    new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            String loginid = PayHelperUtils.getAlipayLoginId(classLoader);
                            String loginAccount = PayHelperUtils.getAlipayLoginAccount(classLoader);
                            L.log("支付宝的登陆" + loginid + "---" + loginAccount);
                            PayHelperUtils.sendLoginId(loginid, loginAccount, "alipay", context);
                        }
                    });
        } catch (Error | Exception e) {
            PayHelperUtils.sendmsg(context, e.getMessage());
        }
    }


    static void replaceDetailPage(final Context context) {
        //hook rpc  QuerySingleBillDetail替换成QuerySingleBillDetailForH5
        ClassLoader classLoader = context.getClassLoader();
        XposedHelpers.findAndHookMethod("com.alipay.mobile.common.rpc.util.RpcInvokerUtil", classLoader, "getOperationTypeValue", Method.class, Object[].class, new

                XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        if (param.getResult() == null) {
                            return;
                        }
                        try {
                            String operationTypeValue = (String) param.getResult();
                            if ("alipay.mobile.bill.QuerySingleBillDetail".equals(operationTypeValue)) {
                                param.setResult("alipay.mobile.bill.QuerySingleBillDetailForH5");
                            }
                        } catch (Exception ex) {
                        }
                    }
                });
    }

    static void billDetail(final Context context, final String bizInNo, String bizType, final String money, final String remark,final String payType) {
        //
        AlipayHookHelper.getBillDetail(bizInNo, bizType, new
                AlipayRpcRunnable() {
                    @Override
                    public void rpcResult(Object obj) {
                        try {
                            Log.i("#####testBroadReceived", "rpcResult:" + JSON.toJSONString(obj));
                            Class<?> resClass = obj.getClass();
                            ///

                            ///

                            Field field = resClass.getDeclaredField("extension");
                            Map<String, String> extension = (Map<String, String>) field.get(obj);
                            String mdata = extension.get("mdata");
                            Log.i("####testBroadReceived", "mdata:" + mdata);
                            if (mdata == null) {
                                return;
                            }
                            JSONObject jsonObject = new JSONObject(mdata);
                            final String conbiz_opp_uid = jsonObject.optString("conbiz_opp_uid");
                            Log.i("####testBroadReceived:", "conbiz_opp_uid:" + conbiz_opp_uid);

                            Intent broadCastIntent = new Intent();
                            broadCastIntent.putExtra("bill_no", bizInNo);
                            broadCastIntent.putExtra("bill_money", money);
                            broadCastIntent.putExtra("bill_remark", remark);
                            broadCastIntent.putExtra("bill_type", "alipay");
                            broadCastIntent.putExtra("bill_pay_user_id", conbiz_opp_uid);
                            broadCastIntent.putExtra("bill_pay_type", payType);
                            broadCastIntent.setAction(BILLRECEIVED_ACTION);
                            context.sendBroadcast(broadCastIntent);

                        } catch (Exception ex) {
                            Log.i("####testBroadReceived:", "getBillDetail Err:" + ex);
                            ex.printStackTrace();
                        }
                    }
                });
    }


    /**
     *
     * @param context
     * @param type
     * @param payType 5充值   1扫码
     */
    static void getBillList(final Context context, final String type,final String payType) {
        L.d("获取账单");
        ClassLoader loader = context.getClassLoader();
        Class ServiceUtil = XposedHelpers.findClass("com.alipay.mobile.beehive.util.ServiceUtil", loader);
        Class RpcService = XposedHelpers.findClass("com.alipay.mobile.framework.service.common.RpcService", loader);
        Class BillListPBRPCService = XposedHelpers.findClass("com.alipay.mobilebill.biz.rpc.bill.v9.pb.BillListPBRPCService", loader);
        final Object RpcProxy = XposedHelpers.callMethod(XposedHelpers.callStaticMethod(ServiceUtil, "getServiceByInterface", RpcService), "getRpcProxy", BillListPBRPCService);
        final Object QueryListReq = XposedHelpers.newInstance(XposedHelpers.findClass("com.alipay.mobilebill.common.service.model.pb.QueryListReq", loader));
        XposedHelpers.setObjectField(QueryListReq, "category", "ALL");
        XposedHelpers.setObjectField(QueryListReq, "pageType", "WaitPayConsumeQuery");
        XposedHelpers.setObjectField(QueryListReq, "paging", XposedHelpers.newInstance(XposedHelpers.findClass("com.alipay.mobilebill.common.service.model.pb.PagingCondition", loader)));
        XposedHelpers.setObjectField(QueryListReq, "needMonthSeparator", Boolean.FALSE);
        XposedHelpers.setObjectField(QueryListReq, "scene", "BILL_LIST");
        long currentTimeMillis = System.currentTimeMillis();
        XposedHelpers.setObjectField(QueryListReq, "startTime", currentTimeMillis - 60 * 3 * 1000);
        XposedHelpers.setObjectField(QueryListReq, "endTime", currentTimeMillis);
        XposedHelpers.setObjectField(QueryListReq, "dateType", "day");
        new Thread() {
            @SuppressLint("CheckResult")
            public void run() {
                List billListItems = (List) XposedHelpers.getObjectField(XposedHelpers.callMethod(RpcProxy, "query", QueryListReq), "billListItems");
                L.d("抓取到:" + billListItems.size() + "条账单");

                String data = JSONParser.toString(billListItems);
                L.d(data);

                JSONArray array = JSON.parseArray(data);
                for (int i = 0; i < array.size(); i++) {
                    com.alibaba.fastjson.JSONObject object = (com.alibaba.fastjson.JSONObject) array.get(i);
                    String orderNo = object.getString("bizInNo");
                    String consumeFee = object.getString("consumeFee").replace("+", "")
                            .replace(",", "");
                    String remark = object.getString("consumeTitle");
                    if (remark.indexOf("-") > -1) {
                        remark = remark.substring(0, remark.indexOf("-"));
                    }

                    L.d("订单号:" + orderNo + "金额" + consumeFee);

                    //获取当前订单,去查看详情
                    L.d("当前订单号:" + orderNo);
                    //替换
                    replaceDetailPage(context);
                    //固码详情
//                    billDetail(context, orderNo, "TRADE", consumeFee, remark);

                    //未开商家服务的
                    billDetail(context, orderNo, type, consumeFee, remark,payType);

                }
            }
        }.start();
    }


    private void securityCheckHook(ClassLoader classLoader) {
        try {
            Class<?> securityCheckClazz = XposedHelpers.findClass("com.alipay.mobile.base.security.CI", classLoader);
            XposedHelpers.findAndHookMethod(securityCheckClazz, "a", String.class, String.class, String.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    Object object = param.getResult();
                    XposedHelpers.setBooleanField(object, "a", false);
                    param.setResult(object);
                    super.afterHookedMethod(param);
                }
            });

            XposedHelpers.findAndHookMethod(securityCheckClazz, "a", Class.class, String.class, String.class, new XC_MethodReplacement() {
                @Override
                protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                    return (byte) 1;
                }
            });
            XposedHelpers.findAndHookMethod(securityCheckClazz, "a", ClassLoader.class, String.class, new XC_MethodReplacement() {
                @Override
                protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                    return (byte) 1;
                }
            });
            XposedHelpers.findAndHookMethod(securityCheckClazz, "a", new XC_MethodReplacement() {
                @Override
                protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                    return false;
                }
            });

        } catch (Error | Exception e) {
            e.printStackTrace();
        }
    }
}